package com.symaster.gameengine.e2d.renderer;

import org.lwjgl.opengl.GL11;

import java.nio.ByteBuffer;

/**
 * 图片拆分渲染器
 * <p>这个渲染器可以将一张完整的图片拆分, 然后选择其中一部分来渲染</p>
 *
 * @author yinmiao
 * @since 2024/9/19
 */
public class ImageSplitRenderer extends ImageRenderer {

    private static final int FLOAT_CACHE_X1 = 0, FLOAT_CACHE_Y1 = 1, FLOAT_CACHE_X2 = 3, FLOAT_CACHE_Y2 = 4,
            FLOAT_CACHE_SIZE_W = 4, FLOAT_CACHE_SIZE_H = 5;
    private final float[] floatCache = new float[6];

    /**
     * 拆分尺寸
     */
    private int splitWidth, splitHeight;
    private int viewX = 0, viewY = 0;
    private Integer lastViewX, lastViewY;

    public ImageSplitRenderer() {
    }

    public ImageSplitRenderer(String fileName) {
        super(fileName);
    }

    public ImageSplitRenderer(ByteBuffer resourceBuffer) {
        super(resourceBuffer);
    }

    public int getSplitWidth() {
        return splitWidth;
    }

    public void setSplitWidth(int splitWidth) {
        this.splitWidth = splitWidth;
    }

    public int getSplitHeight() {
        return splitHeight;
    }

    public void setSplitHeight(int splitHeight) {
        this.splitHeight = splitHeight;
    }

    public int getViewX() {
        return viewX;
    }

    public void setViewX(int viewX) {
        this.viewX = viewX;
    }

    public int getViewY() {
        return viewY;
    }

    public void setViewY(int viewY) {
        this.viewY = viewY;
    }

    @Override
    public int getHeight() {
        return splitHeight;
    }

    @Override
    public int getWidth() {
        return splitWidth;
    }

    /**
     * @return 返回当前帧是否需要刷新Fbo
     */
    @Override
    protected boolean isUpdate() {
        if (super.isUpdate()) {
            return true;
        }

        if (lastViewX == null || lastViewY == null) {
            return true;
        }

        return viewX != lastViewX || viewY != lastViewY;
    }

    /**
     * 子组件使用, 在当前Fbo缓冲区里面绘制
     */
    @Override
    protected void draw() {
        int imgWidth = super.getWidth();
        int imgHeight = super.getHeight();

        int rowLimit = imgWidth / splitWidth;
        int colLimit = imgHeight / splitHeight;

        if (viewX > rowLimit || viewY > colLimit) {
            return;
        }

        floatCache[FLOAT_CACHE_SIZE_W] = (float) splitWidth / (float) imgWidth;
        floatCache[FLOAT_CACHE_SIZE_H] = (float) splitHeight / (float) imgHeight;

        floatCache[FLOAT_CACHE_X1] = viewX * floatCache[FLOAT_CACHE_SIZE_W];
        floatCache[FLOAT_CACHE_Y1] = viewY * floatCache[FLOAT_CACHE_SIZE_H];
        floatCache[FLOAT_CACHE_X2] = floatCache[FLOAT_CACHE_X1] + floatCache[FLOAT_CACHE_SIZE_W];
        floatCache[FLOAT_CACHE_Y2] = floatCache[FLOAT_CACHE_Y1] + floatCache[FLOAT_CACHE_SIZE_H];

        // 启用2D纹理绘制
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        // 绑定到当前图片纹理
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, getImgTexture());

        // 绘制纹理
        GL11.glBegin(GL11.GL_QUADS);

        GL11.glTexCoord2f(floatCache[FLOAT_CACHE_X1], floatCache[FLOAT_CACHE_Y2]);
        GL11.glVertex2f(-1f, -1f);

        GL11.glTexCoord2f(floatCache[FLOAT_CACHE_X2], floatCache[FLOAT_CACHE_Y2]);
        GL11.glVertex2f(1f, -1f);

        GL11.glTexCoord2f(floatCache[FLOAT_CACHE_X2], floatCache[FLOAT_CACHE_Y1]);
        GL11.glVertex2f(1f, 1f);

        GL11.glTexCoord2f(floatCache[FLOAT_CACHE_X1], floatCache[FLOAT_CACHE_Y1]);
        GL11.glVertex2f(-1f, 1f);

        GL11.glEnd();

        // 禁用2D纹理绘制
        GL11.glDisable(GL11.GL_TEXTURE_2D);

        lastViewX = viewX;
        lastViewY = viewY;
    }
}
